/*
 * Created by SharpDevelop.
 * User: Guy Fomi
 * Date: 2/6/2011
 * Time: 2:14 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections;
using System.Collections.Generic;
using HtmlAgilityPack;
using System.Web.Script.Serialization;
using FileSystemDatabase;
using TomatoSynchronizer.Entities;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Linq;
using antiufo.HttpPost;
using System.Collections.Specialized;
using System.Net;

namespace TomatoSynchronizer.Store
{
	/// <summary>
	/// Description of GuestBookStore.
	/// </summary>
	public class GuestBookStore : IStore<GuestBook>
	{
		private Site _site;
		public Site site {
			get { return _site; }
			set { _site = value; }
		}
		
		private HtmlWeb _client;
		
		private JsonDatabase db;
		
		public void PersistItems(List<GuestBook> items)
		{
			db.Write<List<GuestBook>>(items,_site.Name);
		}
		
		public void Truncate()
		{
			throw new NotImplementedException();
		}
		
		public void PersistItem(GuestBook item)
		{
			db.Write<GuestBook>(item,item.guest_books_id);
		}
		
		public bool MoveItem(string itemId, string folderId)
		{
			throw new NotImplementedException();
		}
		
		public GuestBookStore(Site site,HtmlWeb client)
		{
			db = new JsonDatabase("sites/" + site.Name + "/GuestBooks");
			_site = site;
			_client = client;
		}
		
		public bool DeleteItem(string itemId)
		{
			string url = _site.Url + "/admin/json.php?action=delete_guest_book&guest_books_id=" + itemId + "&module=guest_book";
			HtmlDocument doc = _client.Load(url);

			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
			foreach (string key in json.Keys) {
				if (key == "success") {
					var response = bool.Parse(json[key].ToString());
					if (response) {
						db.Delete<GuestBook>(itemId);
					}

					return response;
				}
			}

			throw new Exception("Could not delete the GuestBook " + itemId + " in site " + _site.Name);
		}
		
		public GuestBook[] LoadItems()
		{
			GuestBook[] items = db.Read<GuestBook>();
			foreach(GuestBook item in items)
			{
				item.Store = this;
			}
			return items;
		}
		
		public GuestBook LoadItem(string itemId)
		{
			GuestBook item = db.Read<GuestBook>(itemId);
			if (item != null) {
				item.Store = this;
				return item;
			}

			return null;
		}
		
		public bool Contains(GuestBook item)
		{
			throw new NotImplementedException();
		}
		
		private List<GuestBook> guest_books;
		public List<GuestBook> GetItems()
		{
			db.Truncate();
			guest_books = new List<GuestBook>();
			
			string url = _site.Url + "/admin/json.php?action=list_guest_book&module=guest_book";
			HtmlDocument doc = _client.Load(url);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			Dictionary<string,object> json = serialiser.Deserialize<Dictionary<string,object>>(node.InnerText);
			foreach (string key in json.Keys) {
				if (key == "records") {
					ArrayList recs = (ArrayList)json[key];
					for (int i = 0; i < recs.Count; i++) {
						Dictionary<string, object> record = (Dictionary<string, object>)recs[i];
						GuestBook guest_book = GetItem(record["guest_books_id"].ToString());
						guest_books.Add(guest_book);
						PersistItem(guest_book);
					}
				}
			}
			
			PersistItems(guest_books);
			
			return guest_books;
		}

		public List<GuestBook> DownloadItems()
		{
			guest_books = new List<GuestBook>();
			
			string url = _site.Url + "/admin/json.php?action=list_guest_book&module=guest_book";
			HtmlDocument doc = _client.Load(url);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			Dictionary<string,object> json = serialiser.Deserialize<Dictionary<string,object>>(node.InnerText);
			foreach (string key in json.Keys) {
				if (key == "records") {
					ArrayList recs = (ArrayList)json[key];
					for (int i = 0; i < recs.Count; i++) {
						Dictionary<string, object> record = (Dictionary<string, object>)recs[i];
						GuestBook guest_book = GetItem(record["guest_books_id"].ToString());
						guest_books.Add(guest_book);
					}
				}
			}
			
			return guest_books;
		}
		
		public GuestBook GetItem(string itemId)
		{
			string url = _site.Url + "/admin/json.php?action=load_guest_book&guest_books_id=" + itemId + "&module=guest_book";

			HtmlDocument doc = _client.Load(url);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");

			try {
				JObject json = (JObject)JsonConvert.DeserializeObject(node.InnerText);
				foreach (JProperty property in json.Properties()) {
					if (property.Name == "data") {
						var val = property.Value.ToString();
						GuestBook guest_book = new GuestBook(val);
						guest_book.Store = this;
						return guest_book;
					}
				}

				throw new Exception("Could not load the GuestBook " + itemId);
			} catch (JsonReaderException ex) {
				throw ex;
			}
		}
		
		public bool UpdateItem(GuestBook item)
		{
			var post = new antiufo.HttpPost.HttpPostRequest(_site.Url + "/admin/json.php");

			post.AddField("content",item.content);
			post.AddField("email",item.email);
			post.AddField("module", "guest_book");
			post.AddField("action", "save_guest_book");
			post.AddField("guest_books_id",item.guest_books_id);
			post.AddField("guest_books_status", item.guest_books_status);
			post.AddField("languages_id", item.languages_id);
			post.AddField("title", item.title);
			post.AddField("url", item.url);
			
			var resp = post.PostData();

			Stream s = resp.GetResponseStream();
			StreamReader sr = new StreamReader(s);

			var response = sr.ReadToEnd();
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(response);
			if (json != null) {
				foreach (string key in json.Keys) {
					if (key == "success") {
						return bool.Parse(json[key].ToString());
					}
				}
			}

			throw new Exception("Could not update the GuestBook " + item.title + " in site " + _site.Name);
		}
		
		public string InsertItem(GuestBook item)
		{
			var post = new antiufo.HttpPost.HttpPostRequest(_site.Url + "/admin/json.php");

			post.AddField("content",item.content);
			post.AddField("email",item.email);
			post.AddField("module", "guest_book");
			post.AddField("action", "save_guest_book");
			post.AddField("guest_books_status", item.guest_books_status);
			post.AddField("languages_id", item.languages_id);
			post.AddField("title", item.title);
			post.AddField("url", item.url);
			
			var resp = post.PostData();

			Stream s = resp.GetResponseStream();
			StreamReader sr = new StreamReader(s);

			var response = sr.ReadToEnd();
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			
			try
			{
				IDictionary json = serialiser.Deserialize<IDictionary>(response);
				if (json != null) {
					foreach (string key in json.Keys) {
						if (key == "success") {
							if (bool.Parse(json[key].ToString())) {
								
								var _guest_books = DownloadItems();
								
								foreach(GuestBook info in _guest_books)
								{
									var _info = LoadItem(info.guest_books_id);
									
									if(_info == null)
									{
										PersistItem(info);
										return info.guest_books_id;
									}
								}
							}
						}
					}
				}
			}
			catch(ArgumentException)
			{
				throw new Exception(response);
			}

			throw new Exception("Could not insert the GuestBook " + item.title + " in site " + _site.Name);
		}
	}
}
